package lumis.content.table;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import lumis.content.ContentException;
import lumis.content.ContentManagerFactory;
import lumis.content.core.Content;
import lumis.doui.DouiException;
import lumis.doui.processaction.ProcessActionHandler;
import lumis.doui.table.TableSource;
import lumis.doui.table.field.ITableSourceField;
import lumis.portal.PortalException;
import lumis.portal.UnexpectedException;
import lumis.portal.dao.jdbc.ITransactionJdbc;
import lumis.util.XmlUtil;
import lumis.util.converter.ConvertUtil;

/**
 * Validates that content references exist in a table.
 * <p>
 * This process action handler receives in its configuration a table and 
 * a column.  During runtime it receives an identifier for the items being
 * deleted.  For each of these items it calculates the content identifier
 * and verifies that the content identifier is not being referenced in
 * the column of the table provided.
 * <p>
 *
 * @version $Revision: 9601 $ $Date: 2008-07-18 15:38:17 -0300 (Fri, 18 Jul 2008) $
 * @since 4.2.0
 */
public class ValidateContentReferencesProcessActionHandler extends ProcessActionHandler<TableSource>
{
	public void processAction() throws PortalException
	{
		// get the table and column name
		String table = XmlUtil.readNodeString("parameters/table", this.processActionNode);
		if(table == null)
			throw new DouiException("parameters/table not specified.");
		
		String contentIdColumn = XmlUtil.readNodeString("parameters/contentIdColumn", this.processActionNode);
		if(contentIdColumn == null)
			throw new DouiException("parameters/contentIdColumn not specified.");
		
		String [] pkValues = getPrimaryKeyValues();
		
		if(pkValues != null)
		{
			for(String pkValue : pkValues)
			{
				ValidateContentReference(pkValue, table, contentIdColumn);
			}
		}
		
		addDefaultResponse();
	}
	
	protected String[] getPrimaryKeyValues() throws PortalException
	{
		ITableSourceField primaryKeyField = source.getPrimaryKeyField();
		if (primaryKeyField == null)
			throw new DouiException("STR_PRIMARY_KEY_REQUIRED");
		
		Object pkValues = this.getParameter(primaryKeyField.getId());
		String[] values;
		if (pkValues instanceof String[])
		{
			values = (String[])pkValues;
		}
		else if (pkValues instanceof Object[])
		{
			Collection<String> valuesCollection = ConvertUtil.convert(String.class, (Iterable)pkValues, new ArrayList<String>(), null, null);
			values = valuesCollection.toArray(new String[valuesCollection.size()]);
		}
		else
			values = new String[] { ConvertUtil.convert(String.class, pkValues, null, null) };
	
		if (values == null || values.length == 0)
			throw new DouiException("STR_PRIMARY_KEY_REQUIRED");
		
		return values;
	}

	protected void ValidateContentReference(String itemId, String table, String contentIdColumn) throws PortalException
	{
		try
		{
			Content content = ContentManagerFactory.getContentManager().getContentByItemId(itemId);
			
			String query = "select count("+contentIdColumn+") from "+table+" where "+contentIdColumn+"=?";
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			try
			{
				statement.setString(1, content.getId());
				
				ResultSet results= statement.executeQuery();
				try
				{
					results.next();
					int count = results.getInt(1);
					if(count > 0)
						throw new ContentException("STR_EXISTS_REFERENCES_TO_CONTENT_BEING_DELETED");
				}
				finally
				{
					results.close();
				}
			}
			finally
			{
				statement.close();
			}
		}
		catch(SQLException e)
		{
			throw new UnexpectedException(e);
		}
	}
}
